home *** CD-ROM | disk | FTP | other *** search
/ Floppyshop 2 / Floppyshop - 2.zip / Floppyshop - 2.iso / art&graf.ix / art-4542 / rshade30 / gray22.s < prev    next >
Text File  |  1993-09-06  |  17KB  |  478 lines

  1. ;From gatech!wrdis01!mips!spool.mu.edu!cs.umn.edu!msi.umn.edu!noc.MR.NET!ns!ns!logajan Mon May 20 13:45:34 EDT 1991
  2. ;Article: 39871 of comp.sys.atari.st
  3. ;Path: gatech!wrdis01!mips!spool.mu.edu!cs.umn.edu!msi.umn.edu!noc.MR.NET!ns!ns!logajan
  4. ;From: logajan@ns.network.com (John Logajan)
  5. ;Newsgroups: comp.sys.atari.st
  6. ;Subject: Display 22 levels of gray on color mon.
  7. ;Message-ID: <1991May19.210150.7671@ns.network.com>
  8. ;Date: 19 May 91 21:01:50 GMT
  9. ;Sender: news@ns.network.com
  10. ;Organization: Network Systems Corporation
  11. ;Lines: 436
  12. ;Posted: Sun May 19 16:01:50 1991
  13. ;Originator: logajan@ns
  14. ;Nntp-Posting-Host: ns
  15. ;Sender: kilian
  16. ;Status: OR
  17. ;
  18. ;
  19. ; gray22 -- original code by John Logajan 5-19-91, PUBLIC DOMAIN.
  20. ;                            logajan@ns.network.com
  21. ;
  22. ; This subroutine is called by the ATARI ST COLOR user to go into
  23. ; 22 level grayscale display mode (dithered flicker.)  Any keys pressed
  24. ; from the keyboard will return control back to the user's calling program.
  25. ; Keys pressed will not be disturbed and will be available for inspection
  26. ; by normal TOS routines.  This routine uses 64k just below the normal
  27. ; screen RAM area.
  28. ;
  29. ; This will display a 320x200 minimum window in 22 level grayscale.
  30. ; You can have arbitrarily large virtual displays.  Scrolling the
  31. ; window across the virtual image is accomplished merely by calling this
  32. ; program with a new starting (upper left corner) address.
  33. ;
  34. ; The virtual image must be in the form of one byte per pixel.  Legal
  35. ; intensity values in each byte range from 0 to 21 (decimal.)  The image
  36. ; is organized as left to right and top to bottom.
  37. ;
  38. ; The call to gray22 must include:
  39. ;
  40. ; A0 set to the window starting point (upper left corner) in the image.
  41. ; D0 set to the length of the virtual image horizontal line (bytes).
  42. ;    D0 should never change unless the virtual image size changes.
  43. ;    D0 is *not* 320 unless the virtual image size is the same as the
  44. ;    window size (the window size *is* always 320.)
  45. ;
  46. ; There are three subroutines below.  One initializes everything, one
  47. ; restores everything on exit, one displays the window and also has
  48. ; an entry point for simply going back into display mode without
  49. ; changing the current screen contents (useful for quick returns
  50. ; from invalid keypressed keys.)
  51. ; jsr grayinit -- should be called once to go into low resolution mode.
  52. ;                 Calling grayinit twice or more without intervening
  53. ;                 calls to grayexit will cause original modes to be
  54. ;                 forgotten.
  55. ;
  56. ; jsr grayexit -- should be called once on exit to restore previous modes.
  57. ;                 Don't call grayexit if you haven't yet called grayinit.
  58. ;
  59. ; jsr gray22   -- should be called with A0 and D0 set, to update display.
  60. ;                 Don't call gray22 if you haven't yet called grayinit.
  61. ;
  62. ; jsr grayshow -- should be called to bypass update and continue previous
  63. ;                 display.  gray22 automatically executes grayshow.
  64. ;                 Don't call grayshow if you haven't yet called grayinit
  65. ;                 and gray22 at least once.
  66.  
  67.           text
  68.           even
  69.  
  70.           globl grayinit, grayexit, gray22, grayshow
  71.  
  72. ;
  73. ; Here is gray22, be sure to have called grayinit before calling this.
  74. ; Also be sure to set A0 and D0 before each gray22 call.
  75. ;
  76. gray22:   movem.l   d3-d7/a2-a6,regsave
  77.  
  78.           move.l a0,corner     ; save the starting corner
  79.  
  80.           sub.l #320,d0        ; compute and save the window factor
  81.           move.l d0,wrapit
  82. ;
  83. ; We get 22 shades of gray by flipping between three screens each
  84. ; with different combinations of eight shades of gray (the atari
  85. ; hardware limit.)  The table below shows the general theory:
  86. ; Screen           Screen           Screen
  87. ; 0 1 2  Shade     0 1 2  Shade     0 1 2  Shade
  88. ;
  89. ; 7 7 7   21       4 4 5   13       2 2 1   5
  90. ; 7 7 6   20       4 4 4   12       1 1 2   4
  91. ; 6 6 7   19       4 4 3   11       1 1 1   3
  92. ; 6 6 6   18       3 3 4   10       1 1 0   2
  93. ; 6 6 5   17       3 3 3    9       0 0 1   1
  94. ; 5 5 6   16       3 3 2    8       0 0 0   0
  95. ; 5 5 5   15       2 2 3    7
  96. ; 5 5 4   14       2 2 2    6
  97. ;
  98. ; In addition, to keep flicker to a minimum, we phase dither each intensity
  99. ; with a three horizontal by three vertical pixel intensity interlace.
  100. ; For instance, a block of intensity-18 pixels would be displayed as such:
  101. ;
  102. ; ... First Screenful ...   ... Second Screenful ...   ...Third Screenful...
  103. ; ... 6 6 7 6 6 7 6 6 ...   ... 6 7 6 6 7 6 6 7  ...   ... 7 6 6 7 6 6 7 ...
  104. ; ... 6 7 6 6 7 6 6 7 ...   ... 7 6 6 7 6 6 7 6  ...   ... 6 6 7 6 6 7 6 ...
  105. ; ... 7 6 6 7 6 6 7 6 ...   ... 6 6 7 6 6 7 6 6  ...   ... 6 7 6 6 7 6 6 ...
  106. ; ...      etc        ...   ...       etc        ...   ...       etc     ...
  107. ;
  108.  
  109. ;
  110. ; Do first screen full.
  111. ;
  112.           move.w #-1,-(sp)     ; keep resolution
  113.           move.l phy0,-(sp)    ; switch to phys addr screen #0
  114.           move.l phy0,-(sp)    ; switch to logical addr screen #0
  115.           move.w #5,-(sp)      ; setscreen
  116.           trap #14
  117.           add.l #12,sp
  118.  
  119.           move.l #gtable,a5   ; conversion table base address
  120.           move.l corner,a2    ; get start point
  121.           move.l phy0,a1      ; get screen start address
  122. ;
  123. ; First of three grouped horizontal lines.
  124. ;
  125.           move.w #66,d7       ; 200 lines
  126. b0r1:     move.l #templine,a3 ; where we build a temporary line
  127.           move.w #106,d6      ; 320 bits per line
  128. b0r2:     clr.l d0
  129.           move.b (a2)+,d0 
  130.           move.b (a5,d0),d0   ; dither pixel horz 0 -- line 0
  131.           move.b d0,(a3)+
  132.           clr.l d0
  133.           move.b (a2)+,d0
  134.           move.b 22(a5,d0),d0 ; dither pixel horz 1 -- line 0
  135.           move.b d0,(a3)+
  136.           clr.l d0
  137.           move.b (a2)+,d0
  138.           move.b 44(a5,d0),d0 ; dither pixel horz 2 -- line 0
  139.           move.b d0,(a3)+
  140.           dbf d6,b0r2
  141.           add.l wrapit,a2     ; window correction factor
  142.           subq.l #1,a2        ; backup 1 pixel
  143.           jsr repac320
  144. ;
  145. ; Second of three grouped horizontal lines
  146. ;
  147.           move.l #templine,a3
  148.           move.w #106,d6
  149. b0r3:     clr.l d0
  150.           move.b (a2)+,d0
  151.           move.b 22(a5,d0),d0 ; dither pixel horz 0 -- line 1       
  152.           move.b d0,(a3)+
  153.           clr.l d0
  154.           move.b (a2)+,d0
  155.           move.b 44(a5,d0),d0 ; dither pixel horz 1 -- line 1         
  156.           move.b d0,(a3)+
  157.           clr.l d0
  158.           move.b (a2)+,d0
  159.           move.b (a5,d0),d0   ; dither pixel horz 2 -- line 1
  160.           move.b d0,(a3)+
  161.           dbf d6,b0r3
  162.           add.l wrapit,a2     ; window correction factor
  163.           subq.l #1,a2        ; backup 1 pixel
  164.           jsr repac320
  165. ;
  166. ; Third of three grouped horizontal lines.
  167. ;
  168.           move.l #templine,a3
  169.           move.w #106,d6
  170. b0r4:     clr.l d0
  171.           move.b (a2)+,d0
  172.           move.b 44(a5,d0),d0 ; dither pixel horz 0 -- line 2
  173.           move.b d0,(a3)+
  174.           clr.l d0
  175.           move.b (a2)+,d0
  176.           move.b (a5,d0),d0   ; dither pixel horz 1 -- line 2
  177.           move.b d0,(a3)+
  178.           clr.l d0
  179.           move.b (a2)+,d0
  180.           move.b 22(a5,d0),d0 ; dither pixel horz 2 -- line 2
  181.           move.b d0,(a3)+
  182.           dbf d6,b0r4
  183.           add.l wrapit,a2     ; window correction factor
  184.           subq.l #1,a2        ; backup 1 pixel
  185.           jsr repac320        ; paint a screen line
  186.           dbf d7,b0r1         ; go do next three screen lines
  187. ;
  188. ; Do second screen.
  189. ;
  190.           move.l corner,a2    ; get start point
  191.           move.l phy1,a1      ; get screen start address
  192.           move.w #66,d7       ; 200 lines
  193. b1r1:     move.l #templine,a3 ; where we build a temporary line
  194.           move.w #106,d6      ; 320 bits per line
  195. b1r2:     clr.l d0
  196.           move.b (a2)+,d0
  197.           move.b 22(a5,d0),d0          
  198.           move.b d0,(a3)+
  199.           clr.l d0
  200.           move.b (a2)+,d0
  201.           move.b 44(a5,d0),d0          
  202.           move.b d0,(a3)+
  203.           clr.l d0
  204.           move.b (a2)+,d0
  205.           move.b (a5,d0),d0          
  206.           move.b d0,(a3)+
  207.           dbf d6,b1r2
  208.           add.l wrapit,a2     ; window correction factor
  209.           subq.l #1,a2        ; backup 1 pixel
  210.           jsr repac320
  211.           move.l #templine,a3
  212.           move.w #106,d6
  213. b1r3:     clr.l d0
  214.           move.b (a2)+,d0
  215.           move.b 44(a5,d0),d0          
  216.           move.b d0,(a3)+
  217.           clr.l d0
  218.           move.b (a2)+,d0
  219.           move.b (a5,d0),d0          
  220.           move.b d0,(a3)+
  221.           clr.l d0
  222.           move.b (a2)+,d0
  223.           move.b 22(a5,d0),d0          
  224.           move.b d0,(a3)+
  225.           dbf d6,b1r3
  226.           add.l wrapit,a2     ; window correction factor
  227.           subq.l #1,a2        ; backup 1 pixel
  228.           jsr repac320
  229.           move.l #templine,a3
  230.           move.w #106,d6
  231. b1r4:     clr.l d0
  232.           move.b (a2)+,d0
  233.           move.b (a5,d0),d0          
  234.           move.b d0,(a3)+
  235.           clr.l d0
  236.           move.b (a2)+,d0
  237.           move.b 22(a5,d0),d0          
  238.           move.b d0,(a3)+
  239.           clr.l d0
  240.           move.b (a2)+,d0
  241.           move.b 44(a5,d0),d0          
  242.           move.b d0,(a3)+
  243.           dbf d6,b1r4
  244.           add.l wrapit,a2     ; window correction factor
  245.           subq.l #1,a2        ; backup 1 pixel
  246.           jsr repac320        ; paint a screen line
  247.           dbf d7,b1r1         ; go do next three screen lines
  248. ;
  249. ; Do third screen
  250. ;
  251.           move.l corner,a2    ; get start point
  252.           move.l phy2,a1      ; get screen start address
  253.           move.w #66,d7       ; 200 lines
  254. b2r1:     move.l #templine,a3 ; where we build a temporary line
  255.           move.w #106,d6      ; 320 bits per line
  256. b2r2:     clr.l d0
  257.           move.b (a2)+,d0
  258.           move.b 44(a5,d0),d0          
  259.           move.b d0,(a3)+
  260.           clr.l d0
  261.           move.b (a2)+,d0
  262.           move.b (a5,d0),d0          
  263.           move.b d0,(a3)+
  264.           clr.l d0
  265.           move.b (a2)+,d0
  266.           move.b 22(a5,d0),d0          
  267.           move.b d0,(a3)+
  268.           dbf d6,b2r2
  269.           add.l wrapit,a2     ; window correction factor
  270.           subq.l #1,a2        ; backup 1 pixel
  271.           jsr repac320
  272.           move.l #templine,a3
  273.           move.w #106,d6
  274. b2r3:     clr.l d0
  275.           move.b (a2)+,d0
  276.           move.b (a5,d0),d0          
  277.           move.b d0,(a3)+
  278.           clr.l d0
  279.           move.b (a2)+,d0
  280.           move.b 22(a5,d0),d0          
  281.           move.b d0,(a3)+
  282.           clr.l d0
  283.           move.b (a2)+,d0
  284.           move.b 44(a5,d0),d0          
  285.           move.b d0,(a3)+
  286.           dbf d6,b2r3
  287.           add.l wrapit,a2     ; window correction factor
  288.           subq.l #1,a2        ; backup 1 pixel
  289.           jsr repac320
  290.           move.l #templine,a3
  291.           move.w #106,d6
  292. b2r4:     clr.l d0
  293.           move.b (a2)+,d0
  294.           move.b 22(a5,d0),d0          
  295.           move.b d0,(a3)+
  296.           clr.l d0
  297.           move.b (a2)+,d0
  298.           move.b 44(a5,d0),d0          
  299.           move.b d0,(a3)+
  300.           clr.l d0
  301.           move.b (a2)+,d0
  302.           move.b (a5,d0),d0          
  303.           move.b d0,(a3)+
  304.           dbf d6,b2r4
  305.           add.l wrapit,a2     ; window correction factor
  306.           subq.l #1,a2        ; backup 1 pixel
  307.           jsr repac320        ; paint a screen line
  308.           dbf d7,b2r1         ; go do next three screen lines, else show
  309.  
  310.           bra graysh1
  311. ;
  312. ; This section of the code continuously flips through the three video
  313. ; screens to generate the flicker grayscale effect.  Any keypress will
  314. ; cause a subroutine exit back to the user calling program.
  315. ;
  316. ; You can call this directly if you want to avoid the delay of updating
  317. ; a screen that doesn't need to be updated.  However, it makes no sense
  318. ; to call this if you haven't already called grayinit and gray22 at least
  319. ; once prior.
  320. grayshow: movem.l   d3-d7/a2-a6,regsave
  321.  
  322. graysh1:  move.w #37,-(sp)    ; wait for vsync
  323.           trap #14
  324.           addq.l #2,sp
  325.  
  326.           move.w #-1,-(sp)     ; keep resolution
  327.           move.l phy1,-(sp)    ; switch phys addr to screen #1
  328.           move.l #-1,-(sp)     ; keep logical addr
  329.           move.w #5,-(sp)      ; setscreen
  330.           trap #14
  331.           add.l #12,sp
  332.  
  333.           move.w #37,-(sp)    ; wait for vsync
  334.           trap #14
  335.           addq.l #2,sp
  336.  
  337.           move.w #-1,-(sp)     ; keep res
  338.           move.l phy2,-(sp)    ; switch phys addr to screen #2
  339.           move.l #-1,-(sp)     ; keep logical addr
  340.           move.w #5,-(sp)      ; setscreen
  341.           trap #14
  342.           add.l #12,sp
  343.  
  344.           move.w #37,-(sp)    ; wait for vsync
  345.           trap #14
  346.           addq.l #2,sp
  347.  
  348.           move.w #-1,-(sp)     ; keep res
  349.           move.l phy0,-(sp)    ; switch phys addr to screen #1
  350.           move.l #-1,-(sp)     ; keep logical addr
  351.           move.w #5,-(sp)      ; setscreen
  352.           trap #14
  353.           add.l #12,sp
  354.  
  355.           move.w #$0b,-(sp)   ; check for keypress
  356.           trap #1
  357.           addq.l #2,sp
  358.           tst.w d0
  359.           beq grayshow        ; keep flipping screens if no keypress
  360.  
  361.           movem.l   regsave,d3-d7/a2-a6
  362.           rts                 ; else exit back to calling user program
  363. ;
  364. ; Subroutine to distribute one line's worth of color register numbers
  365. ; into goofy Atari video ram format. (This is five times faster than
  366. ; using the Atari Line-A Put-Pixel A001 routine.)
  367. ;
  368. repac320: move.w #19,d6       ; do 20 groups of 16 pixels (320)
  369.           move.l #templine,a0 ; point to temp line of color registers. 
  370. repack16: move.w #15,d5       ; do 16 pixels
  371. repack:   move.b (a0)+,d0     ; get each color register number.
  372.           roxr.b #1,d0
  373.           roxl.w #1,d1        ; pick off lsb
  374.           roxr.b #1,d0
  375.           roxl.w #1,d2        ; pick off lsb+1
  376.           roxr.b #1,d0
  377.           roxl.w #1,d3        ; pick off lsb+2
  378.           dbf d5,repack
  379.           move.w d1,(a1)+     ; 16 pixel LSB's (a1 points to video ram)
  380.           move.w d2,(a1)+
  381.           move.w d3,(a1)+
  382.           clr.w (a1)+         ; 16 pixel MSB's  (MSB always zero)
  383.           dbf d6,repack16
  384.           rts                 ; return to calling program
  385. ;
  386. ; This routine allocates an additional 64k bytes for two more screens,
  387. ; saves the original palette and resolution for later restore.  And
  388. ; switches to low resolution and installs the grayscale palette.
  389. ;
  390. grayinit: movem.l   d3-d7/a2-a6,regsave
  391.  
  392.           move.w #2,-(sp)     ; get screen physical base address
  393.           trap #14
  394.           addq.l #2,sp
  395.           move.l d0,phy0      ; save address of screen #0
  396.           sub.l #32768,d0 
  397.           move.l d0,phy1      ; save address of screen #1
  398.           sub.l #32768,d0
  399.           move.l d0,phy2      ; save address of screen #2
  400.  
  401.           move.l #oldpal,a5   ; save each color number of the old palette
  402.           move.w #0,d5
  403.           move.w #15,d6
  404. gncolor:  move.w #-1,-(sp)
  405.           move.w d5,-(sp)     ; color number
  406.           move.w #7,-(sp)
  407.           trap #14
  408.           addq.l #6,sp
  409.           move.w d0,(a5)+     ; previous color saved
  410.           addq.w #1,d5
  411.           dbf d6,gncolor
  412.  
  413.           move.w #4,-(sp)     ; get and save original resolution
  414.           trap #14
  415.           addq.l #2,sp
  416.           move.w d0,oldres
  417.  
  418.           move.w #0,-(sp)     ; switch to low res
  419.           move.l #-1,-(sp)    ; keep phys addr
  420.           move.l #-1,-(sp)    ; keep logical addr
  421.           move.w #5,-(sp)     ; setscreen
  422.           trap #14
  423.           add.l #12,sp
  424.  
  425.           move.l #newpal,-(sp) ; install new palette
  426.           move.w #6,-(sp)
  427.           trap #14
  428.           addq.l #6,sp
  429.  
  430.           movem.l   regsave,d3-d7/a2-a6
  431.           rts
  432. ;
  433. ;  This routine restores original resolution, screen, and palette
  434. ;
  435. grayexit: move.w oldres,-(sp) ; old resolution
  436.           move.l phy0,-(sp)   ; old phys addr
  437.           move.l phy0,-(sp)   ; old logical addr
  438.           move.w #5,-(sp)     ; setscreen
  439.           trap #14
  440.           add.l #12,sp
  441.  
  442.           move.l #oldpal,-(sp) ; install old palette
  443.           move.w #6,-(sp)
  444.           trap #14
  445.           addq.l #6,sp
  446.           rts
  447. ;
  448. ; Variable and storage area
  449. ;
  450.           data
  451.           even
  452.  
  453. newpal:   dc.w 0,$111,$222,$333,$444,$555,$666,$777,0,0,0,0,0,0,0,0
  454. oldpal:   dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  455. gtable:   dc.b 0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7
  456.           dc.b 0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7
  457.           dc.b 0,1,0,1,2,1,2,3,2,3,4,3,4,5,4,5,6,5,6,7,6,7
  458. phy0:     dc.l 0
  459. phy1:     dc.l 0
  460. phy2:     dc.l 0
  461. oldres:   dc.l 0
  462. wrapit:   dc.l 0
  463. corner:   dc.l 0
  464.  
  465.           bss
  466.           even
  467.  
  468. regsave:  ds.l 16
  469. templine: ds.l 81
  470.  
  471. ;-- 
  472. ;- John Logajan @ Network Systems; 7600 Boone Ave; Brooklyn Park, MN 55428
  473. ;- logajan@ns.network.com, 612-424-4888, Fax 612-424-2853
  474.  
  475.